<template>
	<div class="tags" v-if="showTags">
		<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
			<ul>
				<li ref="tag" class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index">
					<el-tooltip class="item" effect="dark" :content="item.title" placement="top">
						<router-link :to="item.path" class="tags-li-title">
							{{item.title}}
						</router-link>
					</el-tooltip>
					<span class="tags-li-icon" @click="closeTags(index)">
						<i class="icon iconfont icon-guanbi-biaoqian"></i>
					</span>
				</li>
			</ul>
		</el-scrollbar>
		<div class="tags-close-box">
			<el-dropdown @command="handleTags">
				<el-button size="mini" type="primary">
					标签选项
					<i class="el-icon-arrow-down el-icon--right"></i>
				</el-button>
				<el-dropdown-menu size="small" slot="dropdown">
					<el-dropdown-item command="other">关闭其他</el-dropdown-item>
					<el-dropdown-item command="all">关闭所有</el-dropdown-item>
				</el-dropdown-menu>
			</el-dropdown>
		</div>
	</div>
</template>

<script>
import { mapState, mapMutations} from 'vuex'
const tagAndTagSpacing = 3

export default {
  name: 'tags',
	data() {
		return {}
	},
	computed: {
		...mapState({
			tagsList: state => state.app.tagsList
		}),
		showTags() {
			return this.tagsList.length > 0
		}
	},
	methods: {
		...mapMutations(['setTags', 'delTags']),
		isActive(path) {
			return path === this.$route.fullPath
		},
		// 关闭单个标签
		closeTags(index) {
			this.delTags({
				index,
				callback: res => {
					const delItem = res.delItem
					const item = res.item
					if (item) {
						delItem.path === this.$route.fullPath && this.$router.push(item.path)
					} else {
						this.$router.push('/')
					}
				}
			})
		},
		// 关闭全部标签
		closeAll() {
			this.$store.state.app.tagsList = []
			this.$router.push('/')
		},
		// 关闭其他标签
		closeOther() {
			const tagsList = this.$store.state.app.tagsList
			const curItem = tagsList.fidelItemlter(item => {
				return item.path === this.$route.fullPath
			})
			this.$store.state.app.tagsList = curItem
		},
		handleTags(command) {
			command === 'other' ? this.closeOther() : this.closeAll()
		},
		handleScroll(e) {
			const eventDelta = e.wheelDelta || -e.deltaY * 40
			const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
			$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
		},
		moveToTarget(currentTag) {
			const $container = this.$refs.scrollContainer.$el
			const $containerWidth = $container.offsetWidth
			const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
			const tagList = this.$refs.tag

			let firstTag = null
			let lastTag = null
			let prevTag = null
			let nextTag = null

			// find first tag and last tag
			if (tagList.length > 0) {
				firstTag = tagList[0]
				lastTag = tagList[tagList.length - 1]
			}

			// find preTag and nextTag
			for (let i = 0; i < tagList.length; i++) {
				if (tagList[i] === currentTag) {
					if (i === 0) {
						nextTag = tagList[i].length > 1 && tagList[i + 1]
					} else if (i === tagList.length - 1) {
						prevTag = tagList[i].length > 1 && tagList[i - 1]
					} else {
						prevTag = tagList[i - 1]
						nextTag = tagList[i + 1]
					}
					break
				}
			}

			if (firstTag === currentTag) {
				$scrollWrapper.scrollLeft = 0
			} else if (lastTag === currentTag) {
				$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
			} else {
				// the tag's offsetLeft after of nextTag
				const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing
				// the tag's offsetLeft before of prevTag
				const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing

				if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
					$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
				} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
					$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
				}
			}
		}
	},
	watch: {
		$route(newValue) {
			newValue.name === 'empty' || this.setTags(newValue)
			let curIndex = 0
			this.tagsList.forEach((item, index) => {
				if (item.name === newValue.name) {
					curIndex = index
				}
			})
			this.$nextTick(() => {
				this.moveToTarget(this.$refs['tag'][curIndex])
			})
		},
		tagsList(newVal) {
			localStorage.setItem('tagList', JSON.stringify(newVal))
		}
	},
	created() {
		this.$route.name && this.setTags(this.$route)
	}
}
</script>

<style lang="scss">
@import "../../style/default/variable";
.scroll-container {
  white-space: nowrap;
  position: relative;
  overflow: hidden;
  width: 100%;
  .el-scrollbar__bar {
    bottom: 0px;
  }
  .el-scrollbar__wrap {
    height: 59px;
  }
}
.tags {
  position: relative;
  height: 40px;
  overflow: hidden;
  background: #fff;
  padding-right: 120px;
}

.tags ul {
  box-sizing: border-box;
  height: 100%;
  white-space: nowrap;
}

.tags-li {
  display: inline-block;
  font-size: 13px;
  overflow: hidden;
  cursor: pointer;
  height: 40px;
	line-height: 40px;
	border: 1px solid #fff;
  border-right: 1px solid #f2f2f2;
  background: #fff;
  padding: 0 10px 0 20px;
  vertical-align: middle;
  color: $gray;
  -webkit-transition: all 0.3s ease-in;
  -moz-transition: all 0.3s ease-in;
	transition: all 0.3s ease-in;
	.tags-li-icon {
		margin-left: 10px;
		.iconfont {
      width: 10px;
			color: #ccc;
			font-size: 14px;
		}
	}
}

.tags-li:not(.active):hover {
  background: #f8f8f8;
}

.tags-li.active {
  color: #fff;
  border: 1px solid $blue;
	background-color: $blue;
	.iconfont {
		color: #fff;
	}
}

.tags-li-title {
  float: left;
  max-width: 80px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-right: 5px;
  color: #666;
}

.tags-li.active .tags-li-title {
  color: #fff;
}

.tags-close-box {
  position: absolute;
  right: 0;
  top: 0;
  box-sizing: border-box;
  padding-top: 1px;
  text-align: center;
  width: 120px;
  height: 40px;
  background: #fff;
  box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
	z-index: 10;
	.el-dropdown {
		height: 40px;
		.el-button {
			padding: 12px 15px;
			font-size: 14px;
		}
		.el-button--mini {
			border-radius: 0;
			background: #fff;
			color: $blue;
			border: none;
		}
	}
}
</style>
